﻿using Microsoft.VisualBasic.Logging;
using Newtonsoft.Json.Linq;
using Osklib;
using Osklib.Wpf;
using StorageApp.APIS;
using StorageApp.Service;
using StorageApp.Utility;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.Json.Nodes;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml.Linq;
using ZXing;
using ZXing.Aztec.Internal;
using ZXing.QrCode.Internal;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;

namespace StorageApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>


    public partial class MainWindow : System.Windows.Window
    { 
        private DispatcherTimer timer = new DispatcherTimer();
        private ScanerHook scanlistener = new ScanerHook();
        private Dictionary<string, string?> scrapData = new Dictionary<string, string?> { };
        private Dictionary<string, string?> selectScrap = new Dictionary<string, string?> { };
        private string Operator_id = "";
        private string ?Device_id = null;
        private string next_process_id = "";
        private bool need_device=false;
        public MainWindow()
        {
            InitializeComponent(); 
            scanlistener.ScanerEvent += scan_DataReveived;
            Operator.PreviewMouseUp += Operator_MouseDown;
            InitTimer();
            var isdebug = Method.IniReadValue("isDebug");
            Mouse.AddPreviewMouseDownHandler(this, OnGlobalMouseClick);
            if (isdebug.ToLower()=="true")
                initData("CS250415008201");
        }
        /// <summary>疵点明细单元格单击编辑处理</summary>
        public string? code;
        public string totalpage_str = "0";
        public string pages_str = "1";
        double newWidth = 0;
        double newHeight = 0;
        private async void getScrap()
        {
            setetcrapType_Size(scrapType);
            
            var w = int.Parse(Math.Floor(newWidth / 96).ToString("0"));
            var h = int.Parse(Math.Floor(newHeight / 74).ToString("0"));
           var pagesone= int.Parse((w * h).ToString());
            var res = await api.scrapStatus(pages_str, pagesone.ToString());
            JToken inspect = res["data"]["rows"];
            if (inspect != null)
            {
                var total= res["data"]["total"].ToString();
                totalpage_str = int.Parse((int.Parse(total) / pagesone).ToString()).ToString();
                pages_str = res["data"]["page"].ToString();
                pages.Content = "第" + pages_str + "页";
                totalpage.Content = "共" + totalpage_str + "页";
                scrapData.Clear();
                foreach (var item in inspect)
                {
                    if(!scrapData.ContainsKey(item["defectName"].ToString()))
                        scrapData.Add(item["defectName"].ToString(), item["defectName"].ToString());
                }
            }
            setScrap();
        }

        public async void setEmployee()
        {
            var res = await api.api_employee(next_process_id);
            if (res["data"] != null)
                setOperator(employee_g, res["data"]);
        }

        private void setOperator(System.Windows.Controls.GroupBox box, JToken? optor)
        {

            box.Content = null;
            var stackPanel = new WrapPanel();
            foreach (var item in optor)
            {
                var button = new System.Windows.Controls.Button();
                button.Width = 80;
                button.Height = 50;
                button.Margin = new Thickness(5);
                button.Content = item["name"];
                PropertyHelper.SetProperty(button, item["id"].ToString());
                button.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xA9, 0xF6, 0xB8));


                button.Click += (s, e) => {
                    System.Windows.Controls.Button btn = (System.Windows.Controls.Button)s;
                    string content = btn.Content.ToString();
                    if (content != null)
                    {
                        Operator.Text = content;
                        Operator_id = PropertyHelper.GetProperty(btn); 
                    } 
                };

                stackPanel.Children.Add(button);
            }
            box.Content = stackPanel;
        }

        private void defect_next_page(object sender, RoutedEventArgs e)
        {
            if (totalpage_str == pages_str)
            {
                System.Windows.MessageBox.Show("已经是第一页");
            }
            else
            {
                pages_str=(int.Parse(pages_str)+1).ToString();
                getScrap();
            }
        }
        private void defect_up_page(object sender, RoutedEventArgs e)
        {
            if (pages_str == "1")
            {
                System.Windows.MessageBox.Show("已经是第一页");
            }
            else
            { 
                pages_str = (int.Parse(pages_str) - 1).ToString();
                getScrap();
            }
        }
        private void scrapType_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            System.Windows.Controls.GroupBox groupBox = sender as System.Windows.Controls.GroupBox;
            if (groupBox != null)
            {
                getScrap();
            }
        }
        private void setetcrapType_Size(System.Windows.Controls.GroupBox groupBox)
        { 
            if (groupBox != null)
            {
                // 你可以在这里获取groupBox的新尺寸
                 newWidth = groupBox.ActualWidth;
                 newHeight = groupBox.ActualHeight;
                // 处理groupBox大小变化的代码
            }
        }
     
        private void setScrap()
        {
         
            scrapType.Content = null;
            var scoll = new ScrollViewer();
            scoll.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            scoll.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; 
            var stackPanel = new WrapPanel();
            scoll.Content = stackPanel;
            foreach (var item in scrapData)
            {
                var button = new System.Windows.Controls.Button();
                button.Width = 90;
                button.Height = 70;
                button.Margin = new Thickness(2);
                var textblock = new System.Windows.Controls.TextBlock();
                textblock.Text = item.Value;
                textblock.TextWrapping = System.Windows.TextWrapping.Wrap;
                button.Content = textblock;
                 
                var findbtn = selectScrap.GetValueOrDefault(item.Value ?? "", "");
                if (findbtn != "")
                {
                    button.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xA9, 0xF6, 0xB8));
                }
                else
                    button.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));

                button.Click += (s, e) => {
                    System.Windows.Controls.Button btn = (System.Windows.Controls.Button)s;

                    var key = btn.Content.ToString() ?? "";
                    var findbtn = selectScrap.GetValueOrDefault(key, "");
                    if (findbtn == "")
                    {
                        button.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xA9, 0xF6, 0xB8));
                        selectScrap.Add(key, key);
                    }
                    else
                    {
                        button.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF));
                        selectScrap.Remove(key);
                    }

                };
                stackPanel.Children.Add(button);
            }
            scrapType.Content = stackPanel;
        }
        private void scan_DataReveived(ScanerHook.ScanerCodes codes)
        {
            try
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    if (!string.IsNullOrEmpty(codes.Result))
                    {
                       
                        initData(System.Web.HttpUtility.UrlEncode(codes.Result));
                    }
                }));
            }
            catch (Exception ex)
            {
                 System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

        public void InitTimer()
        {
            timer.Interval = TimeSpan.FromSeconds(2);
            timer.Tick += Timer_Tick;
            timer.Start();
        }
        private void Timer_Tick(object? sender, EventArgs e)
        {
          
            if(scanlistener.isStart==false) {
                scanlistener.Start();
            }
        }

        public async void initData(string? barcodestr)
        {
             barcode.Focus();
            code = barcodestr??"";
             JObject res = await api.getOpenCode(barcodestr); 
             setViewData(res);
            
        }
        public void setflowData(JToken res)
        {
            JToken inspect = res["process_pass"];
            if (inspect != null && inspect.Count() > 0)
            {
                details.ItemsSource = inspect;

            }
        }

        public void setStorageData(JToken res)
        {
            JToken inspect = res["wip"];
            if (inspect != null && inspect.Count() > 0)
            {
                storage.ItemsSource = inspect; 
                //quantity.Text = inspect.First["faultle_quantity"].ToString();
            }
        }
        public void setbom(JToken ?res)
        {
            if (res != null) { 
            JToken inspect = res["details"];
            if (inspect != null && inspect.Count() > 0)
            {
                bom.ItemsSource = inspect;

            }
            }
        }
        JToken? inspectData;
        private void clear()
        {
            barcode.Text = "";
            dyelot.Text = "";
            material.Text = "";
            color.Text = "";
            dyelot.Text = "";
            orderquantity.Text = "";
            packaging_requirements.Text = "";
            customer.Text = "";
            remark.Text = ""; 
            process_content.Text = "";
            flowAdd.Content = "请刷卡";
            flowAdd.IsEnabled = false;  
            bom.ItemsSource = "";
            process_remark.Text = "";
            process_remark1.Text = "";
            craft_category_name.Text = "";

            film_category_name.Text = "";
            soak_name.Text = "";
            water_pressure_name.Text = ""; 
             
            next_process_id = "";
            details.ItemsSource = null;   
            selectScrap.Clear();
            scrap_quantity.Text = "";
        }
        public  void setViewData(JObject res)
        {
            inspectData = res["data"];
            try
            {
                if (inspectData != null && inspectData.Count() > 0)
                {
                    barcode.Text = inspectData["code"].ToString();
                    dyelot.Text = inspectData["dyelot"].ToString();
                    material.Text = inspectData["material"]["name"].ToString();
                    color.Text = inspectData["color_name"].ToString();
                    dyelot.Text = inspectData["dyelot"].ToString();
                    orderquantity.Text = Method.getNum(inspectData["quantity"].ToString()).ToString();
                    packaging_requirements.Text = inspectData["main"]["packaging_requirements"].ToString();
                    customer.Text = inspectData["customer"]["code"].ToString();
                    remark.Text = inspectData["customer"]["remark"].ToString();
                    var process_route = inspectData["main"]["process_route"];
                    var scheduling = inspectData["scheduling"];
                    flowAdd.Content = "结束";
                    flowAdd.IsEnabled = false;
                    var showBom = Method.IniReadValue("showBom");
                 
                    //if (showBom.ToLower() == "true")
                    {   
                        setbom(inspectData["main"]["bom"]);
                    }
                 
                    if (inspectData["craft_category"] is JContainer)
                        craft_category_name.Text = inspectData["craft_category"]?["name"].ToString()??"";
                    if (inspectData["film_category"] is JContainer)
                        film_category_name.Text = inspectData["film_category"]?["name"].ToString()??"";
                    if(inspectData["soak"] is JContainer )
                     soak_name.Text = inspectData["soak"]?["name"]?.ToString()??"";
                    if (inspectData["water_pressure"] is JContainer )
                        water_pressure_name.Text = inspectData["water_pressure"]?["name"].ToString()??"";
                     
                    foreach (var route in process_route["details"])
                    {
                        if (route["front_route_id"].ToString() == inspectData["route_process_id"].ToString())
                        {
                            flowAdd.IsEnabled = true;
                            process_content.Text = inspectData["processrename"]["rename"].ToString() + "->" + route["rename"].ToString();
                            need_device=  route["process"]["need_device"].ToString()=="1";
                            next_process_id = route["process"]["id"].ToString();
                            flowAdd.Content = route["rename"].ToString();
                            foreach(var plan in scheduling)
                            {
                                if (plan["process_name"].ToString()== route["rename"].ToString())
                                {
                                    Device_id = plan["machine_id"].ToString();
                                    if (plan["machine"] is JContainer)
                                        device_name.Text= plan["machine"]?["name"].ToString() ?? "";
                                }
                            }
                        }
                    }
                    setflowData(inspectData);
                    setStorageData(inspectData);
                    setEmployee();
                    selectScrap.Clear();
                    scrap_quantity.Text = "";
                }
            }
            catch (Exception ex) { System.Windows.MessageBox.Show(ex.Message); }
        }
     
        private JObject? getItem()
        {
            JObject col = null;
            if (storage.Items.Count == 0)
            {
                System.Windows.MessageBox.Show("未加载到数据，无法打印！");
            }
            else
            if (storage.SelectedItem != null)
            {
                col = storage.SelectedItem as JObject; 
            }  
            return col;
        }
        private void ItemCellGotFocus(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource.GetType() == typeof(DataGridCell))
            {
                var defectItemGrid = (DataGrid)sender;
                defectItemGrid.BeginEdit(e);

                System.Windows.Controls.Control control = GetFirstChildByType<System.Windows.Controls.Control>((DataGridCell)e.OriginalSource);
                if (control != null)
                {
                    KeyboardService.CloseKeyBoard(this);

                    control.Focus();

                    // 文本全选
                    if (control.GetType() == typeof(System.Windows.Controls.TextBox))
                    {
                        var textBox = (System.Windows.Controls.TextBox)control;

                        textBox.SelectAll();
                    }
                }
            }
        }
        void OnLostFocus(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.TextBox tb = e.Source as System.Windows.Controls.TextBox;
            tb.PreviewMouseDown += new MouseButtonEventHandler(OnPreviewMouseDown);
        }

        void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Controls.TextBox tb = e.Source as System.Windows.Controls.TextBox;
            tb.Focus();
            e.Handled = true;
        }

        void OnGotFocus(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.TextBox tb = e.Source as System.Windows.Controls.TextBox;
            tb.SelectAll();
            tb.PreviewMouseDown -= new MouseButtonEventHandler(OnPreviewMouseDown);
        }
        public static T? GetFirstChildByType<T>(DependencyObject obj) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild((obj), i);
                if (child == null)
                {
                    continue;
                }

                if (child is T castedProp)
                {
                    return castedProp;
                }

                castedProp = GetFirstChildByType<T>(child);

                if (castedProp != null)
                {
                    return castedProp;
                }
            }
            return null;
        }

        public static T? GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
        {
            if (obj == null)
            {
                return null;
            }

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);

                if (child is T t && (t.Name == name | string.IsNullOrEmpty(name)))
                {
                    return t;
                }
                else
                {
                    T grandChild = GetChildObject<T>(child, name);
                    if (grandChild != null)
                    {
                        return grandChild;
                    }
                }
            }
            return null;
        }
        
        public void setColValue(string name, System.Windows.Controls.TextBox textBox)
        { 
            var row = (JObject)textBox.DataContext;
            if (row != null)
            {
                row[name] = (float.Parse(textBox.Text==""?"0": textBox.Text) * 25).ToString("F2");
            }
        }

        public void clearData()
        {
            barcode.Text = "";
            dyelot.Text = "";
            material.Text = "";
            color.Text = "";
            dyelot.Text = "";
            orderquantity.Text = "";
            
            remark.Text = "";
            storage.ItemsSource = null;
            details.ItemsSource = null;
        }
        
        private string mergeremark(string remark,string remark2)
        {
            if (remark2.Trim() != "") {
                if (remark.Trim() != "")
                {
                    return remark + "," + remark2;
                }
                else
                {
                    return remark2;
                }
            }
            return remark;
        }
        private async void flowAdd_Click(object? sender, RoutedEventArgs? e)
        {
            if(Operator_id==null|| Operator_id == "")
            {
                showEmployee();
                return;
            }
            if (need_device && (Device_id == null || Device_id == "" || Device_id == "0"))
            {
                showDevice();
                return;
            }
            var remark = mergeremark("", process_remark.Text) ;
            remark = mergeremark(remark, process_remark1.Text);
            remark = mergeremark(remark, process_remark2.Text);
            remark = mergeremark(remark, process_remark3.Text);
            if (remark.Trim() == "")
            {
                System.Windows.MessageBox.Show("A字架必填");
            }
            if (quantity.Text == "")
            {
                System.Windows.MessageBox.Show("正品数必须手动填写！");
            }
            var res=  await  api.flowAdd(Operator_id, storage.ItemsSource,quantity.Text,scrap_quantity.Text, string.Join(",", selectScrap.Values),speed.Text,temperature.Text,Device_id, remark);
            clear();
        }
        private void showEmployee()
        {
            _operator _Optor = new _operator(next_process_id);

            _Optor.ShowDialog();
            if (_Optor.operator_name != null)
            {
                Operator.Text = _Optor.operator_name;
                Operator_id = _Optor.operator_id;
            }
        }
        private void shoOpenCard()
        {
            opencard _Optor = new opencard();

            _Optor.ShowDialog();
            if (_Optor.open_card != "")
            {
                initData(_Optor.open_card);
            }
        }
        private void showDevice()
        {
            _device _Optor = new _device();

            _Optor.ShowDialog();
            if (_Optor.device_name != null)
            {
                device_name.Text = _Optor.device_name;
                Device_id = _Optor.device_id;
            }
        }
        private void TextBox_rejectKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            setColValue("rejects_quantity", (System.Windows.Controls.TextBox)sender);
        }
        private void TextBox_faultleKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            setColValue("faultle_quantity", (System.Windows.Controls.TextBox)sender);
        }

        private void Operator_MouseDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            showEmployee();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            getScrap();
        }

        private void device_name_PreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            showDevice();
        }

        private async void deletepass_Click(object sender, RoutedEventArgs e)
        {  
         await api.deletePassByWip(storage.ItemsSource);
            initData(code);
        }

      
        private void OnGlobalMouseClick(object sender, MouseButtonEventArgs e)
        {
            // 判断屏幕键盘是否已显示
          
        }

        private void btnMagnifier_Click(object sender, RoutedEventArgs e)
        {
            shoOpenCard();
        }
    }
}